﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DataAccessLayer;
using DTO;
using System.Configuration;
using System.Data;

namespace DAL
{
    public class HoaDonDAL
    {
        private DBManager _dbmanager;

        #region Khởi tạo
        public  HoaDonDAL()
        {
            string ConnectionInfo = ConfigurationManager.AppSettings["ConnectionInfo"];
            _dbmanager = new DBManager(DataProvider.SqlServer, ConnectionInfo);
        }
        #endregion

        #region Tạo Object từ DataReader
        private HoaDonDTO CreateHoaDonFromReader(IDataReader reader)
        {
            HoaDonDTO _hdDTO = new HoaDonDTO();

            _hdDTO.MaHoaDon = reader["MaHoaDon"].ToString();
            _hdDTO.MaKhachHang = reader["MaKhachHang"].ToString();
            _hdDTO.MaNguoiNhanHang = (int)reader["MaNguoiNhanHang"];
            _hdDTO.MaNhanVien = reader["MaNhanVien"].ToString();
            _hdDTO.NgayLapHoaDon = Convert.ToDateTime(reader["NgayLapHoaDon"]);
            _hdDTO.NgayGiao = Convert.ToDateTime(reader["NgayGiao"]);
            _hdDTO.MaHinhThucGiaoHang = (int)reader["MaHinhThucGiaoHang"];
            _hdDTO.MaHinhThucThanhToan = (int)reader["MaHinhThucThanhToan"];
            _hdDTO.MaKhuVucGiaoHang = (int)reader["MaKhuVucGiaoHang"];                        
            _hdDTO.TongTien = (decimal)reader["TongTien"];
            _hdDTO.VAT = (decimal)reader["VAT"];
            _hdDTO.TongTienThanhToan = (decimal)reader["TongTienThanhToan"];
            _hdDTO.TinhTrangHoaDon = (int)reader["TinhTrangHoaDon"];
            _hdDTO.GhiChu = reader["GhiChu"].ToString();

            return _hdDTO;
        }
        #endregion

        #region Thêm hóa đơn
        public void ThemHoaDon(HoaDonDTO hdDTO, List<GioHangDTO> lstGioHangDTO)
        {
           
            try
            {
                _dbmanager.Open();

                // Bắt đầu Transaction
                _dbmanager.BeginTransaction();

                // Thêm hóa đơn
                _dbmanager.CreateParameters(15);
                _dbmanager.AddParameters(0, "@ma_hd", hdDTO.MaHoaDon);
                _dbmanager.AddParameters(1, "@ma_kh", hdDTO.MaKhachHang);
                _dbmanager.AddParameters(2, "@ma_nnh", hdDTO.MaNguoiNhanHang);
                _dbmanager.AddParameters(3, "@ma_nv", hdDTO.MaNhanVien);
                _dbmanager.AddParameters(4, "@ngay_lhd", hdDTO.NgayLapHoaDon);
                _dbmanager.AddParameters(5, "@ngaygiao", hdDTO.NgayGiao);
                _dbmanager.AddParameters(6, "@ma_htgh", hdDTO.MaHinhThucGiaoHang);
                _dbmanager.AddParameters(7, "@ma_httt", hdDTO.MaHinhThucThanhToan);
                _dbmanager.AddParameters(8, "@ma_kvgh", hdDTO.MaKhuVucGiaoHang);
                _dbmanager.AddParameters(9, "@phi_gh", hdDTO.PhiGiaoHang);
                _dbmanager.AddParameters(10, "@tongtien", hdDTO.TongTien);
                _dbmanager.AddParameters(11, "@vat", hdDTO.VAT);
                _dbmanager.AddParameters(12, "@tong_ttt", hdDTO.TongTienThanhToan);
                _dbmanager.AddParameters(13, "@tinh_thd", hdDTO.TinhTrangHoaDon);
                _dbmanager.AddParameters(14, "@ghichu", hdDTO.GhiChu);

                _dbmanager.ExecuteNonQuery(CommandType.StoredProcedure, "usp_ThemHoaDon");

                // Thêm chi tiết hóa đơn
                ChiTietHoaDonDAL cthdDAL = new ChiTietHoaDonDAL();

                int _n = lstGioHangDTO.Count;
                for (int i = 0; i < _n; i++)
                {
                    // Gán dữ liệu từng sản phẩm cho Object Chi tiết hóa đơn
                    ChiTietHoaDonDTO _cthdDTO = new ChiTietHoaDonDTO();

                    _cthdDTO.MaSanPham = lstGioHangDTO[i].MaSanPham;
                    _cthdDTO.MaHoaDon = hdDTO.MaHoaDon;
                    _cthdDTO.DonViTinh = lstGioHangDTO[i].DonViTinh !=null?lstGioHangDTO[i].DonViTinh:"";
                    _cthdDTO.SoLuong = lstGioHangDTO[i].SoLuong;
                    _cthdDTO.DonGia = lstGioHangDTO[i].GiaBan;

                    // Thêm vào table Chi tiết hóa đơn
                    cthdDAL.Them(_cthdDTO, _dbmanager);
                }

                // Thêm thành công thì commit
                _dbmanager.CommitTransaction();
            }
            catch (Exception ex)
            {
                // thêm không thành công thì Rollback
                _dbmanager.RollBackTransaction();
                throw new Exception(ex.Message);
            }
            finally
            {
                _dbmanager.Close();
            }
        }

        #endregion

        #region Hủy hóa đơn
        // Hủy đơn hàng
        public int huyHoaDon(string mahoadon)
        {
            int _index = -1;
            try
            {
                _dbmanager.Open();
                
                _dbmanager.CreateParameters(1);
                _dbmanager.AddParameters(0, "@ma_hd", mahoadon);

                _index = _dbmanager.ExecuteNonQuery(CommandType.StoredProcedure, "usp_HuyHoaDon");
            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }
            finally
            {
                _dbmanager.Close();
            }
            return _index;
        }
        #endregion

        #region Lấy toàn bộ danh sách hóa đơn
        // Lấy toàn bộ danh sách hóa đơn
        public List<HoaDonDTO> GetListHoaDonMotKhachHang(string makhachhang)
        {
            List<HoaDonDTO> _lstHD = new List<HoaDonDTO>();
            IDataReader _reader = null;
            try
            {
                _dbmanager.Open();

                _dbmanager.CreateParameters(1);
                _dbmanager.AddParameters(0, "@ma_kh", makhachhang);

                _reader = _dbmanager.ExecuteReader(CommandType.StoredProcedure, "usp_getListHoaDonMotKhachHang");
                while (_reader.Read())
                    _lstHD.Add(this.CreateHoaDonFromReader(_reader));
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                if (_reader != null)
                {
                    _reader.Close();
                    _dbmanager.Close();
                }
            }
            return _lstHD;
        }
        #endregion

        #region Tạo Object giỏ hàng từ IDataReader
        
        private GioHangDTO CreateGioHangFromReader(IDataReader reader)
        {
            GioHangDTO _ghDTO = new GioHangDTO();

            _ghDTO.MaSanPham = reader["MaSanPham"].ToString();
            _ghDTO.TenSanPham = reader["TenSanPham"].ToString();
            _ghDTO.DonViTinh = reader["DonViTinh"].ToString();
            _ghDTO.SoLuong = Convert.ToInt32(reader["SoLuong"]);
            _ghDTO.GiaBan = (decimal)reader["DonGia"];
            _ghDTO.ThanhTien = (decimal)reader["ThanhTien"];
            
            
            return _ghDTO;
        }
        #endregion

        #region GetHoaDonMotKhachHangVaoGioHang
        public List<GioHangDTO> GetHoaDonMotKhachHangVaoGioHang(string mahoadon)
        {
            List<GioHangDTO> _lstGH= new List<GioHangDTO>();
            IDataReader _reader = null;
            try
            {
                _dbmanager.Open();
                _dbmanager.CreateParameters(1);
                _dbmanager.AddParameters(0, "@ma_hd", mahoadon);
                _reader = _dbmanager.ExecuteReader(CommandType.StoredProcedure, "usp_getHoaDonMotKhachHangVaoGioHang");
                while (_reader.Read())
                    _lstGH.Add(this.CreateGioHangFromReader(_reader));
                
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                if (_reader != null)
                    _reader.Close();
                _dbmanager.Close();
            }
            return _lstGH;
        }
        #endregion

        #region Lấy danh sách hóa đơn
        public List<HoaDonDTO> GetListHoaDon()
        {
            List<HoaDonDTO> _lst = new List<HoaDonDTO>();
            IDataReader _reader = null;
            try
            {
                _dbmanager.Open();

                _reader = _dbmanager.ExecuteReader(CommandType.StoredProcedure, "usp_getListHoaDon");
                while (_reader.Read())
                    _lst.Add(this.CreateHoaDonFromReader(_reader));
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                if (_reader != null)
                    _reader.Close();
            }
            return _lst;
        }
        #endregion

        #region Phương thức lấy danh sách hóa đơn - Hiển thị Gridview
        /// <summary>
        /// Phương thức lấy danh sách hóa đơn - Hiển thị Gridview
        /// </summary>
        /// <returns>List</returns>
        public List<HoaDonDTO> GetListHoaDon(DateTime tu_ngay, DateTime den_ngay)
        {
            List<HoaDonDTO> _lst = new List<HoaDonDTO>();
            IDataReader _reader = null;
            try
            {
                _dbmanager.Open();
                _dbmanager.CreateParameters(2);
                _dbmanager.AddParameters(0, "@tu_ngay", tu_ngay);
                _dbmanager.AddParameters(1, "@den_ngay", den_ngay);
                _reader = _dbmanager.ExecuteReader(CommandType.StoredProcedure, "usp_getListHoaDon");
                while (_reader.Read())
                    _lst.Add(this.CreateHoaDonFromReader(_reader));
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                if (_reader != null)
                    _reader.Close();
            }
            return _lst;
        }
        #endregion

        #region Phương thức lấy thông tin 1 hóa đơn theo mã hóa đơn
        /// <summary>
        /// Phương thức lấy thông tin 1 hóa đơn theo mã hóa đơn
        /// </summary>
        /// <param name="mahd"></param>
        /// <returns>HoaDonDTO</returns>
        public HoaDonDTO GetHoaDon(string mahd)
        {
            HoaDonDTO _hdDTO = new HoaDonDTO();
            IDataReader _reader = null;
            try
            {
                _dbmanager.Open();

                _dbmanager.CreateParameters(1);
                _dbmanager.AddParameters(0, "@ma_hd", mahd);

                _reader = _dbmanager.ExecuteReader(CommandType.StoredProcedure, "usp_getHoaDon");
                while (_reader.Read())
                    _hdDTO = this.CreateHoaDonFromReader(_reader);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                if (_reader != null)
                    _reader.Close();
            }
            return _hdDTO;
        }


        /// <summary>
        /// Phương thức xóa 1 hóa đơn
        /// </summary>
        /// <param name="hd"></param>
        /// <returns></returns>
        public int Xoa(HoaDonDTO hd)
        {
            int index = -1;
            try
            {
                // Mở kết nối
                _dbmanager.Open();

                // Thực thi câu truy vấn
                _dbmanager.CreateParameters(1);
                _dbmanager.AddParameters(0, "@ma_hd", hd.MaHoaDon);
                index = _dbmanager.ExecuteNonQuery(CommandType.StoredProcedure, "usp_XoaHoaDon");
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                if (_dbmanager.Connection.State == ConnectionState.Open)
                    _dbmanager.Close();
            }

            return index;
        }


        /// <summary>
        /// Phương thức cập nhật tình trạng hóa đơn
        /// </summary>
        /// <param name="hd"></param>
        /// <returns></returns>
        public int Sua(HoaDonDTO hd)
        {

            int index = -1;
            try
            {
                // Mở kết nối
                _dbmanager.Open();

                // Thực thi câu truy vấn                
                _dbmanager.CreateParameters(2);
                _dbmanager.AddParameters(0, "@ma_hd", hd.MaHoaDon);
                _dbmanager.AddParameters(1, "@tthd", hd.TinhTrangHoaDon);

                index = _dbmanager.ExecuteNonQuery(CommandType.StoredProcedure, "usp_CapNhatTinhTrangHoaDon");
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                if (_dbmanager.Connection.State == ConnectionState.Open)
                    _dbmanager.Close();
            }

            return index;

        }


        #endregion


        
    }
}